﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Windows.Forms;
using System.Reflection;

namespace MedicalSystems
{
    class DataSourceBuilder
    {
        public DataSourceBuilder()
        {
        }

        public List<Record> dynamicList(string lcCode)
        {
            ICodeCompiler loCompiler = new CSharpCodeProvider().CreateCompiler();

            CompilerParameters loParameters = new CompilerParameters();

            // *** Start by adding any referenced assemblies

            loParameters.ReferencedAssemblies.Add("System.dll");
            loParameters.ReferencedAssemblies.Add("System.Core.dll");
            loParameters.ReferencedAssemblies.Add("System.Xml.Linq.dll");
            loParameters.ReferencedAssemblies.Add("MedicalSystems.exe");
            loParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");


            // *** Load the resulting assembly into memory

            loParameters.GenerateInMemory = true;
            //            loParameters.OutputAssembly = "MedicalSystems.dll";

            // *** Must create a fully functional assembly as a string
            string tmp = "MessageBox.Show(\"Hello\");return new List<Record>();";
            lcCode = @"using System;
                      using System.IO;
                      using System.Windows.Forms;
                        using System.Linq;
                      using System.Collections.Generic;
                    
namespace MedicalSystems {

public class MyClass {
public List<Record> DynamicCode(params object[] Parameters) {
" + lcCode +
         "}   }    }";



            // *** Load the resulting assembly into memory

            loParameters.GenerateInMemory = false;



            // *** Now compile the whole thing

            CompilerResults loCompiled = loCompiler.CompileAssemblyFromSource(loParameters, lcCode);

            if (loCompiled.Errors.HasErrors)
            {
                string lcErrorMsg = "";
                lcErrorMsg = loCompiled.Errors.Count.ToString() + " Errors:";
                for (int x = 0; x < loCompiled.Errors.Count; x++)
                    lcErrorMsg = lcErrorMsg + "\r\nLine: " +
                                 loCompiled.Errors[x].Line.ToString() + " - " +
                                 loCompiled.Errors[x].ErrorText;
                MessageBox.Show(lcErrorMsg + "\r\n\r\n" + lcCode, "Compiler Demo");
                return new List<Record>();
            }
            Assembly loAssembly = loCompiled.CompiledAssembly;
            // *** Retrieve an obj ref – generic type only

            object loObject = loAssembly.CreateInstance("MedicalSystems.MyClass");

            if (loObject == null)
            {
                MessageBox.Show("Couldn't load class.");
                return new List<Record>();
            }
            object[] loCodeParms = new object[1];

            loCodeParms[0] = "West Wind Technologies";

            try
            {
                //Here is the result of the dynamic code
                object loResult = loObject.GetType().InvokeMember(
                                 "DynamicCode", BindingFlags.InvokeMethod,
                                 null, loObject, loCodeParms);
                List<Record> ltNow = (List<Record>)loResult;
                //MessageBox.Show("Method Call Result:\r\n\r\n" +loResult.ToString(), "Compiler Demo");
                return ltNow;
            }

            catch (Exception loError)
            {
                MessageBox.Show(loError.Message, "Compiler Demo");
                return new List<Record>();
            }
        }
    }
}
